Part One: The Scene Graph


Part Two: The VRML Source Code (ballmove.wrl)

Here is the entire VRML 2.0 source code. Type (or paste) this code into a file called "ballmove.wrl".

#VRML V2.0 utf8

Viewpoint {
    position 0 0 3
}

DEF HOURGLASS TimeSensor {
  loop TRUE
  enabled TRUE
  cycleInterval 0.1
  stopTime -1
}

#the object to be animated
DEF BALL Transform {
  translation 0 0 0
  children [        
    Shape {
      appearance Appearance {
        material DEF BALLMAT Material {}
      }
      geometry Sphere { radius 0.1 }
    }
  ]
}

DEF BallScript Script {
  url "ballmove.class"
  scriptType "javabc"
  
  eventIn SFTime move
  eventOut SFVec3f ballpos
}

ROUTE HOURGLASS.cycleTime TO BallScript.move
ROUTE BallScript.ballpos TO BALL.set_translation

Part Three: The Java Source Code (ballmove.java)

Here is the Java source code. Type this into a file called "ballmove.java".

import vrml.*;
import vs.*;

public class ballmove extends Script {
   // connection to send the computed translation
   SFVec3f thePosVec = (SFVec3f)getEventOut("ballpos");

   float [] currPos = new float [3];
   float [] initPos = {0,0,0};

   int numSteps = 10; // steps in each phase
   int currStep = 0;
   int currPhase = 0; //current stage of the animation
   float stepSize = 0;

   public ballmove() {
     int i;
     //initialise the position
     for(i = 0; i < 3; i++) {
        currPos[i] = initPos[i];
     }
   }

   //move : called when the TimeSensor generates events
   public void move(ConstSFTime ev, ConstSFTime time) {
     //If we are at the start of a new phase 
     //compute the increment to be used at each step
     if(currStep == 0) {
        switch (currPhase) {
           case 0 : stepSize = 0.2f/numSteps;
                    break;
           case 1 : stepSize = 0.4f/numSteps;
                    break;
           case 2 : stepSize = -0.4f/numSteps;
                    break;
           case 3 : stepSize = -0.2f/numSteps;
        }
     }
     //update the current position
     for(int i = 0; i < 3; i++) {
        currPos[i] += stepSize;
     }
     //move the ball to new position
     thePosVec.setValue(currPos);
    
     //if we are at the end of a phase
     //update phase and reinitialise  the step count
     if(currStep == numSteps) {
       currStep = 0;
       currPhase = (currPhase+1)%4;      
     }
     else {
       currStep += 1;
     }
   }
}